"""
日志配置模块 - 实现结构化日志记录系统
"""
import structlog
import logging
import logging.handlers
import sys
import json
import traceback
from pathlib import Path
from datetime import datetime
from typing import Dict, Any, Optional
from contextlib import contextmanager
from core.config import settings


class DatabaseOperationLogger:
    """数据库操作日志记录器"""
    
    def __init__(self):
        self.logger = structlog.get_logger("database")
    
    def log_query(self, operation: str, table: str, query: str, params: Optional[Dict] = None, 
                  execution_time: Optional[float] = None, result_count: Optional[int] = None):
        """记录数据库查询操作"""
        self.logger.info(
            "Database query executed",
            operation=operation,
            table=table,
            query=query[:500] if query else None,  # 限制查询长度
            params=params,
            execution_time_ms=execution_time * 1000 if execution_time else None,
            result_count=result_count,
            timestamp=datetime.utcnow().isoformat()
        )
    
    def log_transaction(self, operation: str, tables: list, success: bool, 
                       execution_time: Optional[float] = None, error: Optional[str] = None):
        """记录数据库事务操作"""
        self.logger.info(
            "Database transaction completed",
            operation=operation,
            tables=tables,
            success=success,
            execution_time_ms=execution_time * 1000 if execution_time else None,
            error=error,
            timestamp=datetime.utcnow().isoformat()
        )
    
    def log_connection(self, action: str, pool_size: Optional[int] = None, 
                      active_connections: Optional[int] = None):
        """记录数据库连接操作"""
        self.logger.info(
            "Database connection event",
            action=action,
            pool_size=pool_size,
            active_connections=active_connections,
            timestamp=datetime.utcnow().isoformat()
        )


class APIRequestLogger:
    """API请求和响应日志记录器"""
    
    def __init__(self):
        self.logger = structlog.get_logger("api")
    
    def log_request(self, method: str, path: str, query_params: Optional[Dict] = None,
                   headers: Optional[Dict] = None, body: Optional[Dict] = None,
                   client_ip: Optional[str] = None, user_id: Optional[str] = None):
        """记录API请求"""
        # 过滤敏感信息
        safe_headers = self._filter_sensitive_headers(headers) if headers else None
        safe_body = self._filter_sensitive_body(body) if body else None
        
        self.logger.info(
            "API request received",
            method=method,
            path=path,
            query_params=query_params,
            headers=safe_headers,
            body=safe_body,
            client_ip=client_ip,
            user_id=user_id,
            timestamp=datetime.utcnow().isoformat()
        )
    
    def log_response(self, method: str, path: str, status_code: int, 
                    response_time_ms: float, response_size: Optional[int] = None,
                    error: Optional[str] = None):
        """记录API响应"""
        self.logger.info(
            "API response sent",
            method=method,
            path=path,
            status_code=status_code,
            response_time_ms=response_time_ms,
            response_size_bytes=response_size,
            error=error,
            timestamp=datetime.utcnow().isoformat()
        )
    
    def _filter_sensitive_headers(self, headers: Dict) -> Dict:
        """过滤敏感的请求头信息"""
        sensitive_keys = {'authorization', 'cookie', 'x-api-key', 'x-auth-token'}
        return {k: '***' if k.lower() in sensitive_keys else v for k, v in headers.items()}
    
    def _filter_sensitive_body(self, body: Dict) -> Dict:
        """过滤敏感的请求体信息"""
        if not isinstance(body, dict):
            return body
        
        sensitive_keys = {'password', 'token', 'secret', 'key', 'auth'}
        filtered = {}
        for k, v in body.items():
            if any(sensitive in k.lower() for sensitive in sensitive_keys):
                filtered[k] = '***'
            else:
                filtered[k] = v
        return filtered


class ErrorTracker:
    """错误追踪和调试信息记录器"""
    
    def __init__(self):
        self.logger = structlog.get_logger("error")
    
    def log_error(self, error: Exception, context: Optional[Dict] = None,
                 request_id: Optional[str] = None, user_id: Optional[str] = None):
        """记录错误信息"""
        error_info = {
            "error_type": type(error).__name__,
            "error_message": str(error),
            "traceback": traceback.format_exc(),
            "context": context,
            "request_id": request_id,
            "user_id": user_id,
            "timestamp": datetime.utcnow().isoformat()
        }
        
        self.logger.error("Application error occurred", **error_info)
    
    def log_validation_error(self, field: str, value: Any, error_message: str,
                           context: Optional[Dict] = None):
        """记录数据验证错误"""
        self.logger.warning(
            "Validation error",
            field=field,
            value=str(value)[:100],  # 限制值的长度
            error_message=error_message,
            context=context,
            timestamp=datetime.utcnow().isoformat()
        )
    
    def log_business_error(self, operation: str, error_code: str, error_message: str,
                          context: Optional[Dict] = None):
        """记录业务逻辑错误"""
        self.logger.warning(
            "Business logic error",
            operation=operation,
            error_code=error_code,
            error_message=error_message,
            context=context,
            timestamp=datetime.utcnow().isoformat()
        )


class PerformanceLogger:
    """性能监控日志记录器"""
    
    def __init__(self):
        self.logger = structlog.get_logger("performance")
    
    def log_operation_time(self, operation: str, execution_time_ms: float,
                          context: Optional[Dict] = None):
        """记录操作执行时间"""
        self.logger.info(
            "Operation performance",
            operation=operation,
            execution_time_ms=execution_time_ms,
            context=context,
            timestamp=datetime.utcnow().isoformat()
        )
    
    def log_resource_usage(self, cpu_percent: float, memory_mb: float,
                          active_connections: Optional[int] = None):
        """记录资源使用情况"""
        self.logger.info(
            "Resource usage",
            cpu_percent=cpu_percent,
            memory_mb=memory_mb,
            active_connections=active_connections,
            timestamp=datetime.utcnow().isoformat()
        )


@contextmanager
def log_operation_time(logger, operation: str, context: Optional[Dict] = None):
    """上下文管理器：自动记录操作执行时间"""
    start_time = datetime.utcnow()
    try:
        yield
    finally:
        end_time = datetime.utcnow()
        execution_time = (end_time - start_time).total_seconds() * 1000
        
        if hasattr(logger, 'log_operation_time'):
            logger.log_operation_time(operation, execution_time, context)
        else:
            logger.info(
                f"Operation '{operation}' completed",
                execution_time_ms=execution_time,
                context=context
            )


def setup_logging():
    """配置结构化日志系统"""
    
    # 确保日志目录存在
    log_dir = Path("logs")
    log_dir.mkdir(parents=True, exist_ok=True)
    
    # 创建不同类型的日志文件
    log_files = {
        "app": log_dir / "app.log",
        "database": log_dir / "database.log",
        "api": log_dir / "api.log",
        "error": log_dir / "error.log",
        "performance": log_dir / "performance.log"
    }
    
    # 配置标准库日志
    logging.basicConfig(
        format="%(message)s",
        stream=sys.stdout,
        level=getattr(logging, settings.LOG_LEVEL.upper())
    )
    
    # 配置structlog
    structlog.configure(
        processors=[
            structlog.stdlib.filter_by_level,
            structlog.stdlib.add_logger_name,
            structlog.stdlib.add_log_level,
            structlog.stdlib.PositionalArgumentsFormatter(),
            structlog.processors.TimeStamper(fmt="iso"),
            structlog.processors.StackInfoRenderer(),
            structlog.processors.format_exc_info,
            structlog.processors.UnicodeDecoder(),
            structlog.processors.JSONRenderer()
        ],
        context_class=dict,
        logger_factory=structlog.stdlib.LoggerFactory(),
        wrapper_class=structlog.stdlib.BoundLogger,
        cache_logger_on_first_use=True,
    )
    
    # 配置不同类型的日志处理器
    for log_type, log_file in log_files.items():
        logger = logging.getLogger(log_type)
        logger.setLevel(getattr(logging, settings.LOG_LEVEL.upper()))
        
        # 使用RotatingFileHandler避免日志文件过大
        handler = logging.handlers.RotatingFileHandler(
            log_file,
            maxBytes=10*1024*1024,  # 10MB
            backupCount=5,
            encoding='utf-8'
        )
        
        # JSON格式化器用于结构化日志
        formatter = logging.Formatter('%(message)s')
        handler.setFormatter(formatter)
        
        logger.addHandler(handler)
        logger.propagate = False  # 避免重复日志
    
    # 配置根日志记录器
    root_logger = logging.getLogger()
    
    # 添加控制台处理器
    console_handler = logging.StreamHandler(sys.stdout)
    console_handler.setLevel(getattr(logging, settings.LOG_LEVEL.upper()))
    console_formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    )
    console_handler.setFormatter(console_formatter)
    root_logger.addHandler(console_handler)


def get_logger(name: str = None):
    """获取结构化日志记录器"""
    return structlog.get_logger(name)


# 创建全局日志记录器实例
db_logger = DatabaseOperationLogger()
api_logger = APIRequestLogger()
error_tracker = ErrorTracker()
performance_logger = PerformanceLogger()